package org.jvm.rtda;

/**
 * 封装一些基本类型的存取方法
 *
 * @author 海燕
 * @date 2023/1/12
 */
public class Slots implements Cloneable {

    protected Slot[] localVars;

    public Slots(int size) {
        this.localVars = new Slot[size];
        for (int i = 0; i < this.localVars.length; i++) {
            localVars[i] = new Slot();
        }
    }


    public void setInt(int index, int val) {
        this.localVars[index].setNum(val);
    }


    public int getInt(int index) {
        return this.localVars[index].getNum();
    }

    public boolean getBoolean(int index) {
        return getInt(index) == 1;
    }

    public void setFloat(int index, float val) {
        this.localVars[index].setNum(Float.floatToIntBits(val));
    }


    public float getFloat(int index) {
        return Float.intBitsToFloat(this.localVars[index].getNum());
    }


    /**
     * long型量需要拆成两个int存储
     * long低32位存在数组低位，高位反之
     *
     * @param index
     * @param val
     */
    public void setLong(int index, long val) {
        this.localVars[index].setNum((int) (val & 0x0FFFFFFFFl));
        this.localVars[index + 1].setNum((int) (val >>> 32 & 0x0FFFFFFFFl));
    }


    public long getLong(int index) {
        long low = ((long) this.localVars[index].getNum()) & 0x0FFFFFFFFl;
        long high = ((long) this.localVars[index + 1].getNum() & 0x0FFFFFFFFl) << 32;
        return low | high;
    }

    /**
     * 双精度浮点数套用long型存储
     *
     * @param index
     * @param val
     */
    public void setDouble(int index, double val) {
        setLong(index, Double.doubleToLongBits(val));
    }

    public double getDouble(int index) {
        return Double.longBitsToDouble(getLong(index));
    }

    /**
     * 设置引用类型
     *
     * @param index
     * @param ref
     */
    public void setRef(int index, Object ref) {
        this.localVars[index].setRef(ref);
    }

    public Object getRef(int index) {
        return this.localVars[index].getRef();
    }

    public void setSlot(int index, Slot slot) {
        this.localVars[index] = slot;
    }

    public Slot getSlot(int index) {
        return this.localVars[index];
    }


    @Override
    protected java.lang.Object clone() throws CloneNotSupportedException {
        Slots cloneSlots = new Slots(this.localVars.length);
        for (int i = 0; i < this.localVars.length; i++) {
            cloneSlots.setSlot(i, this.localVars[i].clone());
        }
        return cloneSlots;
    }
}
